package com.xci.platform.core;

import com.xci.platform.helper.StringHelper;
import com.xci.platform.helper.TreeHelper;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 树形结构操作服务
 */
public class TreeOperateService {
    private ITreeOperate treeOperate;

    public TreeOperateService(ITreeOperate treeOperate) {
        this.treeOperate = treeOperate;
    }

    /**
     * 重新生成所有节点路径
     */
    @Transactional(rollbackFor = Exception.class)
    public void rebuildPath() {
        rebuildPath(Constant.RootNodeId);
    }

    /**
     * 重新生成Tree路径
     *
     * @param parendId 上级主键
     */
    @Transactional(rollbackFor = Exception.class)
    public void rebuildPath(String parendId) {
        List<Tree> all = treeOperate.queryTreeModelList();
        if (all == null || all.size() == 0) return;
        Map<String, Tree> store = new HashMap<>();

        if (StringHelper.isBlank(parendId) || parendId.equals(Constant.RootNodeId)) {
            List<Tree> roots = all.stream().filter(p -> p.getParentId().equals(Constant.RootNodeId)).collect(Collectors.toList());
            for (Tree item : roots) {
                rebuildPathCore(all, store, item);
            }
        } else {
            Optional<Tree> parentOptional = all.stream().filter(p -> p.getId().equals(parendId)).findFirst();
            if (parentOptional.isPresent()) {
                Tree parent = parentOptional.get();
                rebuildPathCore(all, store, parent);
            }
        }

        if (store.size() == 0) return;
        for (Tree item : store.values()) {
            String id = item.getId();
            String path = item.getPath();
            treeOperate.updatePathById(id, path);
        }
    }

    private static void rebuildPathCore(List<Tree> all, Map<String, Tree> store, Tree parent) {
        String parentId = parent.getId();
        String parentPath = parent.getPath();
        if (StringHelper.isBlank(parentId) || StringHelper.isBlank(parentPath)) return;
        List<Tree> children = all.stream().filter(p -> p.getParentId().equals(parentId)).collect(Collectors.toList());
        if (children.size() == 0) return;
        children.sort(Comparator.comparing(Tree::getPath));
        for (int i = 0; i < children.size(); i++) {
            Tree item = children.get(i);
            String itemId = item.getId();
            String path = item.getPath();
            String newPath = TreeHelper.buildPath(parentPath, (i + 1));
            if (!newPath.equals(path)) {
                item.setPath(newPath);
                store.putIfAbsent(itemId, item);
            }
            rebuildPathCore(all, store, item);
        }
    }

    /**
     * 更新父节点和路径
     *
     * @param nodeIndexs 节点父节点和序号数组
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateParentAndPath(TreeNodeIndex[] nodeIndexs) {
        if (nodeIndexs == null || nodeIndexs.length == 0) return;

        for (TreeNodeIndex item : nodeIndexs) {
            String id = item.getId();
            String parentId = item.getParentId();
            String parentPath;
            if (StringHelper.isBlank(parentId) || parentId.equals(Constant.RootNodeId)) {
                parentPath = Constant.Empty;
            } else {
                parentPath = treeOperate.queryPathById(parentId);
            }
            Integer index = item.getIndex();
            String path = TreeHelper.buildPath(parentPath, index + 1);
            treeOperate.updateParentAndPathById(id, parentId, path);
        }
        //更新叶子状态
        updateLeafStatus();
    }

    /**
     * 更新节点叶子状态
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateLeafStatus() {
        List<Tree> all = treeOperate.queryTreeModelList();
        if (all == null || all.size() == 0) return;
        Map<String, Integer> store = new HashMap<>();
        for (Tree model : all) {
            String id = model.getId();
            boolean hasChilds = all.stream().anyMatch(p -> p.getParentId().equals(id));
            Integer leaf = hasChilds ? 0 : 1;
            if (!model.getLeaf().equals(leaf)) {
                store.putIfAbsent(id, leaf);
            }
        }
        if (store.size() > 0) {
            for (Map.Entry<String, Integer> item : store.entrySet()) {
                treeOperate.updateLeafById(item.getKey(), item.getValue());
            }
        }
    }

    /**
     * 生成新建节点路径
     *
     * @param parendId 新建节点的上级主键
     */
    public String buildNewPath(String parendId) {
        String parentPath = Constant.Empty;
        if (StringHelper.isNotBlank(parendId) && !parendId.equals(Constant.RootNodeId)) {
            parentPath = treeOperate.queryPathById(parendId);
        }
        Integer index = treeOperate.queryChildCountById(parendId);
        return TreeHelper.buildPath(parentPath, index + 1);
    }
}
